import datetime

import uuid
from django.db import models
from django.contrib.auth.models import User as AUTH_USER


# 证券地址
class ExchangeAddress(models.Model):
    id = models.IntegerField(primary_key=True, auto_created=True)
    stock_jqdata_name = models.CharField(default="", max_length=8)  # 聚宽数据前缀
    stock_sina_name = models.CharField(default="", max_length=8)  # 新浪数据前缀
    stock_address_name = models.CharField(null=False, default="", max_length=64)  # 交易所名称


# 期货交易所名称
class FuturesExchangeAddress(models.Model):
    id = models.IntegerField(primary_key=True, auto_created=True)
    abbreviated_name = models.CharField(default="", max_length=8)  # 简称
    enchange_name_address_name = models.CharField(null=False, default="", max_length=64)  # 交易所名称

    def convert2jqdata(self):
        self


# 股票数据
class Stock(models.Model):
    exchange_address = models.ForeignKey(to='ExchangeAddress', to_field='id', on_delete=True, null=True)
    id = models.IntegerField(primary_key=True, auto_created=True)
    name = models.CharField(null=False, default="", max_length=16)  # 证券名称
    abbreviated_name = models.CharField(null=False, default="", max_length=64)  # 证券名称缩写
    code = models.CharField(null=False, max_length=16)  # 证券交易代码
    last_update_time = models.DateTimeField(null=True)  # 最近数据更新日期
    start_date = models.DateTimeField(null=True)  # 上市日期
    end_date = models.DateTimeField(null=True)  # 退市日期，如果没有退市则为2200-01-01
    type = models.CharField(null=False, default="", max_length=16)  # 证券类型 stock股票 fund 基金


# 期货数据 需要每日更新
class Futures(models.Model):
    futures_exchange_address = models.ForeignKey(to='FuturesExchangeAddress', to_field='id', on_delete=True, null=True)
    id = models.IntegerField(primary_key=True, auto_created=True)
    name = models.CharField(null=False, default="", max_length=16)  # 期货合约名称
    code = models.CharField(null=False, max_length=16)  # 交易代码
    physical_delivery_date = models.DateTimeField(null=True)  # 交割日期


# 基金数据
class Fund(models.Model):
    exchange_address = models.ForeignKey(to='ExchangeAddress', to_field='id', on_delete=True, default=1)
    id = models.IntegerField(primary_key=True, auto_created=True)
    name = models.CharField(null=False, default="", max_length=16)  # 证券名称
    abbreviated_name = models.CharField(null=False, default="", max_length=64)  # 证券名称缩写
    code = models.CharField(null=False, max_length=16)  # 证券交易代码
    last_update_time = models.DateTimeField(null=True)  # 最近数据更新日期
    start_date = models.DateTimeField(null=True)  # 上市日期
    end_date = models.DateTimeField(null=True)  # 退市日期，如果没有退市则为2200-01-01
    type = models.CharField(null=False, default="", max_length=16)  # 证券类型 stock股票 fund 基金


# 大盘指数
class MarketIndex(models.Model):
    exchange_address = models.ForeignKey(to='ExchangeAddress', to_field='id', on_delete=True)  # 交易所地址
    id = models.IntegerField(primary_key=True, auto_created=True)
    name = models.CharField(null=False, default="", max_length=16)  # 证券名称
    abbreviated_name = models.CharField(null=False, default="", max_length=64)  # 证券名称缩写
    code = models.CharField(null=False, max_length=16)  # 证券交易代码
    last_update_time = models.DateTimeField(null=True)  # 最近数据更新日期
    start_date = models.DateTimeField(null=True)  # 上市日期
    end_date = models.DateTimeField(null=True)  # 退市日期，如果没有退市则为2200-01-01
    type = models.CharField(null=False, default="", max_length=16)  # 证券类型 stock股票 market_index 大盘


class StockInfo(models.Model):
    stock = models.ForeignKey(to='Stock', to_field='id', on_delete=True, null=True)
    sysconf = models.ForeignKey(to='SysConf', to_field='id', on_delete=True, null=True)

    today_open = models.FloatField(null=False,default=0.01)  # 1：”27.55″，今日开盘价；
    yestoday_close = models.FloatField(null=False,default=0.01)  # 2：”27.25″，昨日收盘价；
    current_price = models.FloatField(null=False,default=0.01)  # 3：”26.91″，当前价格；
    high = models.FloatField(null=False,default=0.01)  # 4：”27.55″，今日最高价；
    low = models.FloatField(null=False,default=0.01)  # 5：”26.20″，今日最低价；
    volume = models.FloatField(null=False,default=0.01)  # 成交量
    money = models.FloatField(null=False,default=0.01)  # 成交额

    call_auction_a1_p = models.FloatField(null=False,default=0.01)  # 6：”26.91″，竞买价，即“买一”报价；
    call_auction_b1_p = models.FloatField(null=False,default=0.01)  # 7：”26.92″，竞卖价，即“卖一”报价；

    call_auction_a1_v = models.FloatField(null=False,default=0.01)  # 10，“买一”买量
    call_auction_b1_v = models.FloatField(null=False,default=0.01)  # 11“卖一”卖量；

    call_auction_a2_v = models.FloatField(null=False,default=0.01)  # 12“买二” 量
    call_auction_a2_p = models.FloatField(null=False,default=0.01)  # 13“买二” 价
    call_auction_a3_v = models.FloatField(null=False,default=0.01)  # 6：买三” 量
    call_auction_a3_p = models.FloatField(null=False,default=0.01)  # 7：买三” 价
    call_auction_a4_v = models.FloatField(null=False,default=0.01)  # 6：买四” 量
    call_auction_a4_p = models.FloatField(null=False,default=0.01)  # 7：买四” 价
    call_auction_a5_v = models.FloatField(null=False,default=0.01)  # 7：买五” 量
    call_auction_a5_p = models.FloatField(null=False,default=0.01)  # 7：买五” 价

    call_auction_b2_v = models.FloatField(null=False,default=0.01)  # 12“卖二” 量
    call_auction_b2_p = models.FloatField(null=False,default=0.01)  # 12“卖二” 价
    call_auction_b3_v = models.FloatField(null=False,default=0.01)  # 12“卖三” 量
    call_auction_b3_p = models.FloatField(null=False,default=0.01)  # 12“卖三” 价
    call_auction_b4_v = models.FloatField(null=False,default=0.01)  # 12“卖四” 量
    call_auction_b4_p = models.FloatField(null=False,default=0.01)  # 12“卖四” 价
    call_auction_b5_v = models.FloatField(null=False,default=0.01)  # 12“卖五” 量
    call_auction_b5_p = models.FloatField(null=False,default=0.01)  # 12“卖五” 价


# 行业类
class Industry(models.Model):
    name = models.CharField(max_length=64, default="", null=False)  # 行业名称
    code = models.CharField(max_length=64, default="", null=False)  # 行业代码
    start_date = models.DateTimeField()  # 开始日期
    abbreviation_name = models.CharField(max_length=64, default="", null=False)  # 缩写
    industry_level = models.CharField(max_length=64, default="", null=False)  # 等级


# 概念类
class Concept(models.Model):
    name = models.CharField(max_length=64, default="", null=False)  # 概念名称
    code = models.CharField(max_length=64, default="", null=False)  # 概念代码
    start_date = models.DateTimeField(null=True)  # 开始日期


class StockIndustry(models.Model):
    stock = models.ForeignKey(to='Stock', to_field='id', on_delete=True, null=True)  # 股票
    industry = models.ForeignKey(to='Industry', to_field='id', on_delete=True, null=True)  # 所属行业


class StockConcept(models.Model):
    stock = models.ForeignKey(to='Stock', to_field='id', on_delete=True, null=True)  # 股票
    concept = models.ForeignKey(to='Concept', to_field='id', on_delete=True, null=True)  # 所属概念


# 系统数据状态
class DataState(models.Model):
    name = models.CharField(max_length=64, default="", null=False)  # 数据名称
    update_datetime = models.DateTimeField(null=True)  # 最新更新时间


# 规则列表
class RuleInfo(models.Model):
    sysconf = models.ForeignKey(to='SysConf', to_field='id', on_delete=True)
    model_id = models.IntegerField(null=False, default=1)  # 当前规则使用模型
    name = models.CharField(null=True, max_length=1024)  # 规则名称
    name_en = models.CharField(null=True, max_length=1024)  # 规则英文名
    create_datetime = models.DateTimeField(default=datetime.datetime.now(), null=False)  # 规则创建日期
    update_datetime = models.DateTimeField(null=True)  # 回测日期
    max_back_measurable = models.FloatField(null=False, default=0.0)  # 最大回测收益率
    mean_back_measurable = models.FloatField(null=True, default=0.0)  # 平均回测收益率


# 托管预测模型代码
class ManagedCode(models.Model):
    sysconf = models.ForeignKey(to='SysConf', to_field='id', on_delete=True)
    accuracy = models.FloatField(null=False, default=0.0)  # 预测模型精度
    name = models.CharField(null=True, max_length=1024)  # 模型名称
    create_datetime = models.DateTimeField(default=datetime.datetime.now(), null=False)  # 模型创建日期
    update_datetime = models.DateTimeField(null=True)  # 训练日期
    model_paramater = models.CharField(null=True, max_length=1024)  # 训练参数
    train_time = models.IntegerField(null=True)  # 训练时长s
    model_file = models.BinaryField(null=True)  # 模型二进制文件
    stock_id = models.IntegerField(null=True)  # 预测股票ID
    content = models.CharField(max_length=64, default="", null=False)  # 内容
    preview = models.CharField(max_length=64, default="", null=False)  # 代码描述
    code_size = models.CharField(max_length=64, default="", null=False)  # 代码大小


# 被回测股
class BackMeasurable(models.Model):
    stock_id = models.IntegerField(null=False)  # 股票ID
    back_measurable = models.FloatField(null=False, default=0.0)  # 回测收益
    back_measurable_date = models.DateTimeField(default=datetime.datetime.now(), null=False)  # 回测日期
    rule_info = models.ForeignKey(to='RuleInfo', to_field='id', on_delete=True)


# 系统配置
class SysConf(models.Model):
    id = models.IntegerField(auto_created=True, primary_key=True)
    user = models.OneToOneField(AUTH_USER, on_delete=models.CASCADE)
    main_model = models.IntegerField(null=False, default=1)  # 主模型
    predict_start_time = models.DateTimeField(null=False, default=datetime.datetime.now())  # 预测开始时间
    predict_end_time = models.DateTimeField(null=False, default=datetime.datetime.now())  # 预测结束时间
    my_capital = models.FloatField(null=False, default=5000)  # 我的资金
    my_cash = models.FloatField(null=False, default=5000)  # 在途资金 #建立委托单后会冻结资金
    main_rule = models.IntegerField(null=False, default=1)  # 主规则
    sh_price = models.FloatField(null=False, default=0.0018)  # 上海交易所手续费
    sh_min_price = models.FloatField(null=False, default=5)  # 上海交易所最低手续费
    stamp_tax = models.FloatField(null=False, default=0.01)  # 印花税
    transfer_feed = models.FloatField(null=False, default=0.0002)  # 过户费
    login_ip_address = models.CharField(max_length=64, default="", null=False)  # 登录IP地址
    login_ip_city = models.CharField(max_length=128, default="", null=False)  # 登录城市
    sz_price = models.FloatField(default=0.00207, null=False)  # 深圳交易所手续费
    sz_min_price = models.FloatField(null=False, default=5)  # 深圳交易所最低手续费


# 数据更新
class DataUpdateTask(models.Model):
    sysconf = models.ForeignKey(to='SysConf', to_field='id', on_delete=True)  # 属于哪一个配置
    task_name = models.CharField(max_length=64, default="", null=False)  # 任务名称
    task_function = models.CharField(max_length=64, default="", null=False)  # 任务函数名
    update_start_time = models.DateTimeField(default=datetime.datetime.now(), null=False)  # 任务最近一次开始时间
    update_end_time = models.DateTimeField(default=datetime.datetime.now(), null=False)  # 任务最近一次结束时间
    task_schedule = models.FloatField(null=False, default=0.0)  # 任务进度
    task_state = models.BooleanField(default=False, null=False)  # 任务执行状态
    task_result = models.CharField(max_length=64, default="", null=False)  # 任务返回值
    task_cost = models.DateTimeField(default=datetime.datetime.strptime('0:0:0', "%H:%M:%S"), null=False)  # 任务耗时


# 自选股
class MyStcock(models.Model):
    sysconf = models.ForeignKey(to='SysConf', to_field='id', on_delete=True)  # 属于哪一个配置
    stock = models.ForeignKey(to='StockInfo', to_field='id', on_delete=False)  # 股票名称
    current_price = models.FloatField(default=0.0, null=False)  # 当前价格
    current_chg = models.FloatField(default=0.0, null=False)  # 当前涨跌幅
    chg_price = models.FloatField(default=0.0, null=False)  # 当前涨跌额


# 我的持仓
class OpenInterests(models.Model):
    sysconf = models.ForeignKey(to='SysConf', to_field='id', on_delete=True)  # 属于哪一个配置
    stock = models.ForeignKey(to='StockInfo', to_field='id', on_delete=False)  # 股票名称
    number = models.IntegerField(null=False, default=0)  # 持仓数量
    price = models.FloatField(default=0.0, null=False)  # 买入价格
    buy_time = models.DateTimeField(default=datetime.datetime.now(), null=False)  # 买入时间


# 委托订单
class CommitOrder(models.Model):
    sysconf = models.ForeignKey(to='SysConf', to_field='id', on_delete=True)  # 属于哪一个配置
    stock_info = models.ForeignKey(to='StockInfo', to_field='id', on_delete=False)  # 股票名称
    state = models.ForeignKey(to='OrderState', to_field='id', on_delete=True)  # 订单完成状态 1为完成 0未完成 2撤单
    order_type = models.ForeignKey(to='OrderType', to_field='id', on_delete=True)  # 订单完成状态 1为完成 0未完成 2撤单
    price = models.FloatField(default=0.0, null=False)  # 买入价格
    number = models.FloatField(default=0, null=False)  # 买入数量
    order_id = models.UUIDField(default=uuid.uuid4, null=False)  # 买入数量
    create_time = models.DateTimeField(default=datetime.datetime.now(), null=False)  # 订单创建时间


# 订单类型 买入 卖出
class OrderType(models.Model):
    order_type = models.IntegerField(default=0, null=False)  # 类型
    type_name = models.CharField(default="undo", null=False,max_length=16)  # 类型名称

# 订单状态
class OrderState(models.Model):
    state = models.IntegerField(default=0, null=False)  # 状态
    state_name = models.CharField(default="undo", null=False,max_length=16)  # 状态名称

class APIKeys(models.Model):
    username = models.CharField(max_length=64, default="", null=False)  # 用户名
    password = models.CharField(max_length=64, default="", null=False)  # 密码
    content = models.CharField(max_length=64, default="", null=False)  # 描述
    preview = models.CharField(max_length=64, default="", null=False)  # 简介
    api_type = models.CharField(max_length=64, default="", null=False)  # 接口类型
